From 9c445b92946cb7345e5ca04dd577c523149080e8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 3 May 2015 12:41:04 -0700 Subject: [PATCH] Update to rust master, picking up metadata mtime changes This commit adds a new `MTime` structure specifically for dealing with modification times across platforms. --- Cargo.lock | 7 ++- src/cargo/lib.rs | 2 +- src/cargo/ops/cargo_rustc/fingerprint.rs | 18 ++++---- src/cargo/sources/path.rs | 7 +-- src/cargo/util/mod.rs | 2 + src/cargo/util/mtime.rs | 57 ++++++++++++++++++++++++ src/rustversion.txt | 2 +- 7 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 src/cargo/util/mtime.rs diff --git a/Cargo.lock b/Cargo.lock index 5a0710e23..0571e5198 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "registry 0.1.0", "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tar 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -276,8 +276,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "tar" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "tempdir" diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 3738e97fe..904f4d48e 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -1,5 +1,5 @@ #![deny(unused)] -#![feature(fs_time)] +#![feature(metadata_ext)] #![cfg_attr(test, deny(warnings))] #[cfg(test)] extern crate hamcrest; diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index ecc62f025..8537974f2 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -4,7 +4,7 @@ use std::io::{BufReader, SeekFrom}; use std::path::{Path, PathBuf}; use core::{Package, Target, Profile}; -use util; +use util::{self, MTime}; use util::{CargoResult, Fresh, Dirty, Freshness, internal, profile, ChainError}; use super::Kind; @@ -96,7 +96,7 @@ pub struct Fingerprint { #[derive(Clone)] enum LocalFingerprint { Precalculated(String), - MtimeBased(Option, PathBuf), + MtimeBased(Option, PathBuf), } impl Fingerprint { @@ -110,7 +110,7 @@ impl Fingerprint { LocalFingerprint::MtimeBased(Some(n), _) if !force => n.to_string(), LocalFingerprint::MtimeBased(_, ref p) => { debug!("resolving: {}", p.display()); - try!(fs::metadata(p)).modified().to_string() + try!(MTime::of(p)).to_string() } }; debug!("inputs: {} {} {:?}", known, self.extra, deps); @@ -311,7 +311,7 @@ fn is_fresh(loc: &Path, new_fingerprint: &Fingerprint) -> CargoResult { Ok(old_fingerprint == new_fingerprint) } -fn calculate_target_mtime(dep_info: &Path) -> CargoResult> { +fn calculate_target_mtime(dep_info: &Path) -> CargoResult> { macro_rules! fs_try { ($e:expr) => (match $e { Ok(e) => e, Err(..) => return Ok(None) }) } @@ -324,7 +324,7 @@ fn calculate_target_mtime(dep_info: &Path) -> CargoResult> { Some(Ok(line)) => line, _ => return Ok(None), }; - let mtime = try!(fs::metadata(dep_info)).modified(); + let mtime = try!(MTime::of(dep_info)); let pos = try!(line.find(": ").chain_error(|| { internal(format!("dep-info not in an understood format: {}", dep_info.display())) @@ -342,10 +342,10 @@ fn calculate_target_mtime(dep_info: &Path) -> CargoResult> { file.push(' '); file.push_str(deps.next().unwrap()) } - match fs::metadata(&cwd.join(&file)) { - Ok(ref stat) if stat.modified() <= mtime => {} - Ok(ref stat) => { - info!("stale: {} -- {} vs {}", file, stat.modified(), mtime); + match MTime::of(&cwd.join(&file)) { + Ok(file_mtime) if file_mtime <= mtime => {} + Ok(file_mtime) => { + info!("stale: {} -- {} vs {}", file, file_mtime, mtime); return Ok(None) } _ => { info!("stale: {} -- missing", file); return Ok(None) } diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index 3e2ea0f08..80aa68ed5 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -9,7 +9,8 @@ use git2; use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry}; use ops; -use util::{self, CargoResult, internal, internal_error, human, ChainError, Config}; +use util::{self, CargoResult, internal, internal_error, human, ChainError}; +use util::{MTime, Config}; pub struct PathSource<'a, 'b: 'a> { id: SourceId, @@ -289,14 +290,14 @@ impl<'a, 'b> Source for PathSource<'a, 'b> { return Err(internal_error("BUG: source was not updated", "")); } - let mut max = 0; + let mut max = MTime::zero(); for file in try!(self.list_files(pkg)).iter() { // An fs::stat error here is either because path is a // broken symlink, a permissions error, or a race // condition where this path was rm'ed - either way, // we can ignore the error and treat the path's mtime // as 0. - let mtime = fs::metadata(&file).map(|s| s.modified()).unwrap_or(0); + let mtime = MTime::of(&file).unwrap_or(MTime::zero()); warn!("{} {}", mtime, file.display()); max = cmp::max(max, mtime); } diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index 095884d77..e29fa5844 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -15,6 +15,7 @@ pub use self::to_url::ToUrl; pub use self::to_semver::ToSemver; pub use self::vcs::{GitRepo, HgRepo}; pub use self::sha256::Sha256; +pub use self::mtime::MTime; pub mod config; pub mod errors; @@ -31,3 +32,4 @@ pub mod lev_distance; mod dependency_queue; mod sha256; mod vcs; +mod mtime; diff --git a/src/cargo/util/mtime.rs b/src/cargo/util/mtime.rs new file mode 100644 index 000000000..c0701fd73 --- /dev/null +++ b/src/cargo/util/mtime.rs @@ -0,0 +1,57 @@ +use std::fmt; +use std::fs; +use std::io; +use std::path::Path; + +/// A helper structure to represent the modification time of a file. +/// +/// The actual value contined within is platform-specific and does not have the +/// same meaning across platforms, but comparisons and stringification can be +/// significant among platforms. +#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)] +pub struct MTime { + seconds: u64, + nanos: u32, +} + +impl MTime { + pub fn zero() -> MTime { + MTime { seconds: 0, nanos: 0 } + } + + pub fn of(p: &Path) -> io::Result { + let metadata = try!(fs::metadata(p)); + Ok(MTime::from(&metadata)) + } +} + +impl<'a> From<&'a fs::Metadata> for MTime { + #[cfg(unix)] + fn from(meta: &'a fs::Metadata) -> MTime { + use std::os::unix::prelude::*; + let raw = meta.as_raw(); + // FIXME: currently there is a bug in the standard library where the + // nanosecond accessor is just accessing the seconds again, once + // that bug is fixed this should take nanoseconds into account. + MTime { seconds: raw.mtime() as u64, nanos: 0 } + } + + #[cfg(windows)] + fn from(meta: &'a fs::Metadata) -> MTime { + use std::os::windows::prelude::*; + + // Windows write times are in 100ns intervals, so do a little math to + // get it into the right representation. + let time = meta.last_write_time(); + MTime { + seconds: time / (1_000_000_000 / 100), + nanos: ((time % (1_000_000_000 / 100)) * 100) as u32, + } + } +} + +impl fmt::Display for MTime { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}.{:09}s", self.seconds, self.nanos) + } +} diff --git a/src/rustversion.txt b/src/rustversion.txt index 6008959d3..29bc1583f 100644 --- a/src/rustversion.txt +++ b/src/rustversion.txt @@ -1 +1 @@ -2015-04-29 +2015-05-03 -- 2.30.2